package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {

    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    /**
     * 新建套餐
     * 要调用两张表进行存储:Setmeal(套餐表)  Setmeal_dish(套餐菜品关系表)
     *
     * @param setmealDto
     */
    @Override
    @Transactional
    public void save(SetmealDto setmealDto) {
        Setmeal setmeal = new Setmeal();
        // 将setmealDto里面的信息拷贝到setmeal封装类中
        BeanUtils.copyProperties(setmealDto, setmeal);
        // 保存套餐到套餐表中
        this.save(setmeal);

        // 获取套餐保存到setmeal表中自动生成的id
        Long setmealId = setmeal.getId();
        // 获取套餐中的关联菜品
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        // 由于菜品没有setmeal_id的id值,所以需要设置
        for (SetmealDish setmealDish : setmealDishes) {
            setmealDish.setSetmealId(setmealId);

            // 设置完setmeal_id的值后,将数据存入Setmeal_dish(套餐菜品关系表)中
            setmealDishService.save(setmealDish);
        }
    }

    /**
     * 套餐分页查询
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public Page page(int page, int pageSize, String name) {
        // 创建分页查询构造器
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);
        Page<SetmealDto> setmealDtoPage = new Page<>();

        // 条件查询
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(name != null, Setmeal::getName, name);
        // 设置排序
        queryWrapper.orderByAsc(Setmeal::getUpdateTime).orderByDesc(Setmeal::getCreateTime);
        // 执行查询,查询后,数据封装到setmealPage
        this.page(setmealPage, queryWrapper);
        // 将setmealPage数据拷贝一份到setmealDtoPage中(封装数据的records没有拷贝过来,因为类型不一样)
        BeanUtils.copyProperties(setmealPage,setmealDtoPage);
        // 遍历records,并设置到SetmealDto类型的records中
        List<Setmeal> records = setmealPage.getRecords();
        // 创建一个List集合,接收SetmealDto类型的数据
        List<SetmealDto> records1 = new ArrayList<>();
        for (Setmeal record : records) {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(record,setmealDto);

            Long categoryId = record.getCategoryId();
            Category category = categoryService.getById(categoryId);
            String categoryName = category.getName();
            setmealDto.setCategoryName(categoryName);

            records1.add(setmealDto);
        }
        // 将创建的records1集合放入setmealDtoPage中
        setmealDtoPage.setRecords(records1);

        return setmealDtoPage;
    }

    /**
     * 套餐修改返回数据
     *      调两张表:setmeal套餐表  setmeal_dish套餐与菜品关系表
     * @param id
     * @return
     */
    @Override
    public SetmealDto getSetmeal(Long id) {
        SetmealDto setmealDto = new SetmealDto();
        // 查询setmeal表格,获取套餐中处菜品信息外的所有数据
        Setmeal setmeal = this.getById(id);
        // 将setmeal中的数据全部拷贝到SetmealDto中
        BeanUtils.copyProperties(setmeal,setmealDto);

        // 查询setmeal_dish表中的数据
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,id);
        // 查询
        List<SetmealDish> list = setmealDishService.list(queryWrapper);
        // 将查询结果放入setmealDto对象中
        setmealDto.setSetmealDishes(list);

        return setmealDto;
    }

    /**
     * 套餐修改
     * @param setmealDto
     */
    @Override
    @Transactional
    public void updateSetmeal(SetmealDto setmealDto) {
        // 获取修改套餐的id
        Long id = setmealDto.getId();
        // 删除该套餐的数据信息,然后重新存储
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SetmealDish::getSetmealId,id);
        setmealDishService.remove(queryWrapper);    // 删除套餐与菜品关系表中的数据

        this.removeById(id);    // 删除套餐表中的数据

        this.save(setmealDto);  // 直接调用本类中的新建套餐方法,将数据传入
    }

    /**
     * 套餐起售/停售修改
     * @param status
     * @param ids
     */
    @Override
    public void status(int status, List ids) {
        // 根据ids集合查找出所有的套餐
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Setmeal::getId,ids);
        List<Setmeal> setmealList = this.list(queryWrapper);

        // 遍历套餐,分别设置satus的值
        for (Setmeal setmeal : setmealList) {
            setmeal.setStatus(status);
            // 数据更新后修改数据库(方式一:单独修改)
            //this.updateById(setmeal);
        }
        // 更新数据后修改数据库(方式二:一起修改)
        this.updateBatchById(setmealList);
    }

    /**
     * 套餐删除
     *      要删除两张表中的数据: Setmeal套餐表  Setmeal_dish套餐与菜品关系表
     * @param ids
     */
    @Override
    @Transactional
    public void delete(List<Long> ids) {
        // 删除Setmeal_dish表中的数据
        LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SetmealDish::getSetmealId,ids);
        setmealDishService.remove(queryWrapper);

        // 删除Setmeal表中的数据
        LambdaQueryWrapper<Setmeal> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(Setmeal::getId,ids);
        this.remove(queryWrapper1);

    }
}
